package com.airlines.crewassignment.service.ruleverification.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.airlines.common.TimeUtil;
import com.airlines.crewassignment.constant.CrewConstant;
import com.airlines.crewassignment.constant.RuleConstant;
import com.airlines.crewassignment.domain.Crew;
import com.airlines.crewassignment.domain.CrewLinkLineRoster;
import com.airlines.crewassignment.domain.CrewPositionAssignment;
import com.airlines.crewassignment.domain.Position;
import com.airlines.crewassignment.domain.rule.AssignmentRule;
import com.airlines.crewassignment.domain.util.AirportUtil;
import com.airlines.crewassignment.domain.util.CrewPositionAssignmentUtil;
import com.airlines.crewassignment.domain.util.CrewRestUtil;
import com.airlines.crewassignment.domain.util.DutyDurationUtil;
import com.airlines.crewassignment.domain.util.FlightDurationUtil;
import com.airlines.crewassignment.domain.util.LinkLineLoopUtil;
import com.airlines.crewassignment.domain.util.SkillUtil;
import com.airlines.crewassignment.entity.ruleverification.RuleVerification;
import com.airlines.crewassignment.service.optaplanner.OptaplannerService;
import com.airlines.crewassignment.service.rule.AssignmentRuleService;
import com.airlines.crewassignment.service.ruleverification.RuleHardCheckService;

/**
 * @author xxxx
 * @date 2018年7月24日 
 * @description
 */
@Service
public class RuleHardCheckServiceImpl implements RuleHardCheckService{

	@Autowired
	private  OptaplannerService optaplannerService;
	@Autowired
	private AssignmentRuleService assignmentRuleService;
	
	@Override
	public List<RuleVerification> ruleHardCheckF(DateTime flightDateStart,DateTime flightDateEnd, CrewLinkLineRoster crewLinkLineRoster){
		if(crewLinkLineRoster == null){
			crewLinkLineRoster = optaplannerService.crewLinkLineRosterInit(CrewConstant.DUTY_F,flightDateStart, flightDateEnd);
		}
		
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		List<Crew> crewList = crewLinkLineRoster.getCrewList();
		
		for(Position p : positionList){
			for(Crew c : crewList){
				if(StringUtils.equals(p.getWorkcode(), c.getWorkcode())){
					p.setCrew(c);
				}
			}
		}
		List<RuleVerification> ruleHardCheckALl = new ArrayList<>();
		ruleHardCheckALl.addAll(this.F_H0001(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0002(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0005(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0006(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0007(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0008(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0009(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0010(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0014(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0015(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0016(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0017(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0018(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H0020(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H1002(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H1003(crewLinkLineRoster));
		ruleHardCheckALl.addAll(this.F_H1005(crewLinkLineRoster));

		return ruleHardCheckALl;
	}
	
	


	private List<RuleVerification> F_H0001(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}
		
			boolean ck = SkillUtil.positionSkillCk(p, p.getCrew());
			String remark = "";
			int ruleScore = 0;
			if(!ck){
				
				ruleScore = -assignmentRule.getRuleScore();
				remark = "不符合排班授权";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	
	private List<RuleVerification> F_H0002(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}
		
			boolean ck = SkillUtil.crewExamineCk(p, p.getCrew());
			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "证照或者资质等有效期属性，在所飞航班时间范围内是无效的";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		
		
		return ruleVerificationList;
	}
	
	private List<RuleVerification> F_H0005(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}
		
			boolean ck = p.getCrew().getAge() > RuleConstant.MAX_AGE ? false :true;
			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "年龄大于"+RuleConstant.MAX_AGE;
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		
		
		return ruleVerificationList;
	}
	
	//F_H0006	同一机组中已年满60周岁机组成员不得多于一名
	private List<RuleVerification> F_H0006(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			if(p.getCrew().getAge() >= RuleConstant.LIMIT_NUM_AGE){
				for(Position pOther : positionList){
					if(StringUtils.equals(pOther.getCrewLinkLineKey(), p.getCrewLinkLineKey())
							&& StringUtils.isNotBlank(pOther.getWorkcode())
							&& !StringUtils.equals(pOther.getWorkcode(), p.getWorkcode())
							&& pOther.getCrew().getAge() >= RuleConstant.LIMIT_NUM_AGE){
						
						ck = false;
					}
				}	
			}
			

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "同一机组有2名以上飞行员年龄超过"+RuleConstant.LIMIT_NUM_AGE;
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	
	//F_H0007	国际航线，机组成员ICAO等级不能低于ICAO4
	private List<RuleVerification> F_H0007(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			if(p.getLinkLine().getInternationalFlg() == true 
					&& !StringUtils.equals(p.getCrew().getSkill().getEnglishLevel(),"ICAO4")
					&& !StringUtils.equals(p.getCrew().getSkill().getEnglishLevel(),"ICAO5")
					){
				ck = false;
			}
			
			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "国际航线,飞行员英语等级低于ICAO4";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		
		
		return ruleVerificationList;
	}
	
	//F_H0008	与外籍飞行员同一机组时，机组成员ICAO等级不能低于ICAO4
	private List<RuleVerification> F_H0008(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			if(p.getCrew().getNationCn() != true){
				for(Position pOther : positionList){
					if(StringUtils.equals(pOther.getCrewLinkLineKey(), p.getCrewLinkLineKey())
							&& StringUtils.isNotBlank(pOther.getWorkcode())
							&& !StringUtils.equals(pOther.getWorkcode(), p.getWorkcode())
							&& pOther.getCrew().getNationCn() == true
							&& !StringUtils.equals(pOther.getCrew().getSkill().getEnglishLevel(),"ICAO4")
							&& !StringUtils.equals(pOther.getCrew().getSkill().getEnglishLevel(),"ICAO5")){
						
						ck = false;
					}
				}	
			}
			

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "与外籍飞行员同一机组时，机组成员ICAO等级低于ICAO4";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	
	//F_H0009	在该连线所涉及的所有机型上，90天内有过3次起落经历
	private List<RuleVerification> F_H0009(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			List<CrewPositionAssignment> cpaListForCrew = this.getCpaListForCrew(crewLinkLineRoster, p);
			
			if(CrewPositionAssignmentUtil.isNotEmpty(cpaListForCrew)
				&& SkillUtil.getMinUpdownCount90Days(cpaListForCrew,p.getCrew()) < 3){
					ck = false;
			}

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "90天起落次数低于3次";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	
	
	//F_H0010	如果包含特殊机场，则机长应具备相应的资质
	private List<RuleVerification> F_H0010(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			if(p.getSerialNo()==1
					&& AirportUtil.specialAirportCk(p.getLinkLine().getSpecialAirportList(),p.getCrew().getSkill().getSpecialAirportList()) == false
					){
				ck = false;
			}
			
			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "机长不具备特殊机场资质";
			}
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
		}
		return ruleVerificationList;
	}
	//F_H0014飞行机组成员每日历月最大飞行时间100小时
	private List<RuleVerification> F_H0014(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			List<CrewPositionAssignment> cpaListForCrew = this.getCpaListForCrew(crewLinkLineRoster, p);
			
			if(CrewPositionAssignmentUtil.isNotEmpty(cpaListForCrew)
	       			&& FlightDurationUtil.getMaxFlightDurationEveryMonth(cpaListForCrew,p.getCrew()) > 100*60){
					ck = false;
			}

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "月飞行时间超过100小时";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
    //F_H0015	飞行机组成员每日历年最大飞行时间900小时
	private List<RuleVerification> F_H0015(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			List<CrewPositionAssignment> cpaListForCrew = this.getCpaListForCrew(crewLinkLineRoster, p);
			
			if(CrewPositionAssignmentUtil.isNotEmpty(cpaListForCrew)
	            	&& FlightDurationUtil.getMaxFlightDurationEveryYear(cpaListForCrew,p.getCrew()) > 900*60){
					ck = false;
			}

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "年飞行行时间超过900小时";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	////F_H0016	飞行机组成员每7个日历日最大飞行值勤期60小时
	private List<RuleVerification> F_H0016(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			List<CrewPositionAssignment> cpaListForCrew = this.getCpaListForCrew(crewLinkLineRoster, p);
			
			if(CrewPositionAssignmentUtil.isNotEmpty(cpaListForCrew)
	            	&&  DutyDurationUtil.getMaxDutyDurationEveryWeek(cpaListForCrew,p.getCrew(),crewLinkLineRoster)  > 60*60){
					ck = false;
			}

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "7个日历日飞行值勤期超过60小时";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	
	////F_H0017	飞行机组成员每日历月最大飞行值勤期210小时
	private List<RuleVerification> F_H0017(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			List<CrewPositionAssignment> cpaListForCrew = this.getCpaListForCrew(crewLinkLineRoster, p);
			
			if(CrewPositionAssignmentUtil.isNotEmpty(cpaListForCrew)
	            	&&  DutyDurationUtil.getMaxDutyDurationEveryMonth(cpaListForCrew,p.getCrew())  >210*60){
					ck = false;
			}

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "每日历月飞行值勤期超过210小时";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	//F_H0018	执行飞行任务前144小时，应至少包含连续48小时休息期
	private List<RuleVerification> F_H0018(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			List<CrewPositionAssignment> cpaListForCrew = this.getCpaListForCrew(crewLinkLineRoster, p);
			
			if(CrewPositionAssignmentUtil.isNotEmpty(cpaListForCrew)
	            	&&  !CrewRestUtil.has48xRestBefore144(cpaListForCrew,p.getCrew(),crewLinkLineRoster.getCrewLinkLineRosterGlobalValue())){
					ck = false;
			}

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "飞行任务前144小时，不包含连续48小时休息期";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	
	//F_H0020	飞行值勤期开始前，机组成员至少获得连续10小时休息期
	private List<RuleVerification> F_H0020(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			List<CrewPositionAssignment> cpaListForCrew = this.getCpaListForCrew(crewLinkLineRoster, p);
			
			if(CrewPositionAssignmentUtil.isNotEmpty(cpaListForCrew)
	            	&&  !CrewRestUtil.has10xRestBefore(cpaListForCrew,p.getCrew(),crewLinkLineRoster.getCrewLinkLineRosterGlobalValue())){
					ck = false;
			}

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "飞行值勤期开始前，没有连续10小时休息期";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	
	//F_H1002	同一天一个人只能出现在一个任务环上
	private List<RuleVerification> F_H1002(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())
					|| StringUtils.isBlank(p.getLinkLine().getTaskLoopFact())){
				continue;
			}

			boolean ck = true;
			List<CrewPositionAssignment> cpaListForCrew = this.getCpaListForCrew(crewLinkLineRoster, p);
			
			if(CrewPositionAssignmentUtil.isNotEmpty(cpaListForCrew)){
				for(CrewPositionAssignment c : cpaListForCrew ){
					if(DateUtils.isSameDay(c.getPosition().getFlightDate(), p.getFlightDate())
							&&c.getPosition().getLinkLine().getTaskLoopFact() != null
							&&!StringUtils.equals(c.getPosition().getLinkLine().getTaskLoopFact(), p.getLinkLine().getTaskLoopFact())){
						ck = false;
					}
				}
			}

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "同一天出现2个任务环";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	
	//F_H1003	同一个任务，每个号位的飞行员不能相同
	private List<RuleVerification> F_H1003(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			for(Position pOther : positionList){
				if(StringUtils.equals(pOther.getCrewLinkLineKey(), p.getCrewLinkLineKey())
						&& StringUtils.equals(pOther.getWorkcode(), p.getWorkcode())
						&& !StringUtils.equals(pOther.getPositionId().toString(), p.getPositionId().toString())){
					ck = false;
				}
			}

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "同一个任务安排了多次";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	
	//F_H1005	同一个飞行员，在不同的连线上，时间不同重复
	private List<RuleVerification> F_H1005(CrewLinkLineRoster crewLinkLineRoster) {
		List<RuleVerification>  ruleVerificationList = new ArrayList<>();
		List<Position> positionList = crewLinkLineRoster.getPositionList();
		String ruleCode = Thread.currentThread().getStackTrace()[1].getMethodName();
		AssignmentRule assignmentRule = this.getAssignmentRule(crewLinkLineRoster, ruleCode);
		if(!assignmentRuleService.assignmentRuleAbled(assignmentRule)){
			return ruleVerificationList;
		}
		for(Position p : positionList){
			if(StringUtils.isBlank(p.getWorkcode())){
				continue;
			}

			boolean ck = true;
			for(Position pOther : positionList){
				if(StringUtils.equals(pOther.getWorkcode(), p.getWorkcode())
						&& !StringUtils.equals(pOther.getPositionId().toString(), p.getPositionId().toString())){
					
					if(LinkLineLoopUtil.positionIsIntersection(p,pOther)){
						ck = false;
					};
				}
			}

			String remark = "";
			int ruleScore = 0;
			if(!ck){
				ruleScore = -assignmentRule.getRuleScore();
				remark = "时间安排冲突";
			}
			
			RuleVerification r = this.getRuleVerification(p, ck, remark, ruleCode, ruleScore);
			ruleVerificationList.add(r);
			
		}
		return ruleVerificationList;
	}
	
	/**
	 * 从解决方案中获取规则
	 * @param crewLinkLineRoster
	 * @param ruleCode
	 * @return
	 */
	@Override
	public AssignmentRule getAssignmentRule(CrewLinkLineRoster crewLinkLineRoster,String ruleCode){
		List<AssignmentRule> assignmentRuleList = crewLinkLineRoster.getAssignmentRuleList();
		for(AssignmentRule a : assignmentRuleList){
			if(StringUtils.equals(a.getRuleCode(), ruleCode)){
				return a;
			}
		}
		
		return null;
	}
	
	
	/**
	 * 得分构造
	 * @param p
	 * @param resultFlag
	 * @param remark
	 * @param ruleCode
	 * @param ruleScore
	 * @return
	 */
	@Override
	public RuleVerification getRuleVerification(Position p,boolean resultFlag,String remark,String ruleCode,Integer ruleScore){
		RuleVerification r = new RuleVerification();
		r.setDutyCode(p.getDutyCode());
		r.setFlightDate(p.getFlightDate());
		r.setCrewLinkLineNo(p.getCrewLinkLineNo());
		r.setWorkcode(p.getWorkcode());
		r.setRuleCode(ruleCode);
		if(ruleScore == null){
			ruleScore =0;
		}
		r.setRuleScore(ruleScore);
		r.setResult(resultFlag == true? "Y":"N");
		r.setRemark(remark);
		r.setIsDelete(0);
		r.setCreateTime(TimeUtil.getyyyyMMddHHmmss());
		return r;
	}
	
	/**
	 * 从解决方案中获取某个号位飞行员的所有的连线
	 * @param crewLinkLineRoster
	 * @param p
	 * @return
	 */
	@Override
	public List<CrewPositionAssignment> getCpaListForCrew(CrewLinkLineRoster crewLinkLineRoster,Position p){
		List<CrewPositionAssignment> cpaListForCrew = new  ArrayList<>();
		List<CrewPositionAssignment> cpaList = crewLinkLineRoster.getCrewPositionAssignmentList();
		for(CrewPositionAssignment cpa : cpaList){
			Position pOther = cpa.getPosition();
			if(StringUtils.isNotBlank(pOther.getWorkcode())
					&& StringUtils.equals(pOther.getWorkcode(), p.getWorkcode())){
				cpaListForCrew.add(cpa);
			}
		}	
		
		return cpaListForCrew;
		
	}
}
